package utils;

import java.io.IOException;
import java.io.OutputStream;

/**
 * Se utiliza para realizar el empaquetado o marshalling de los mensajes
 * recibidos
 * 
 * @author upv - Bernabéu, Muñoz, Galdámez
 * 
 */
public class Marshall {

    private OutputStream os;

    public Marshall(OutputStream os) {
	this.os = os;
    }

    /**
     * Pone un entero en el outputstream
     * 
     * @param v
     */
    public void putInt(int v) {
	int i;
	byte[] b = new byte[4];
	// Para empaquetar un entero vamos obteniendo cada uno de sus bytes.//
	for (i = 0; i < 4; i++) {
	    b[3 - i] = (byte) (v % 256);
	    v = v / 256;
	}
	try {
	    // Al final, se escribe en el OutputStream
	    os.write(b);
	} catch (IOException ioe) {
	}
    }

    /**
     * Empaqueta un entero.
     * 
     * @param v
     *            Entero largo que se queire enviar
     */
    public void putLong(long v) {
	putInt((int) v); // Los enteros largos se empaquetan //
    } // igual que los int. //

    /**
     * Empaqueta un boolean
     * 
     * @param v
     *            Boleano que se queire enviar
     */
    public void putBool(boolean v) {
	try { // Los booleanos usan un byte. A 1 //
	    if (v) { // si era cierto, a 0 si es falso. //
		os.write(1);
	    } else {
		os.write(0);
	    }
	} catch (IOException ioe) {
	}
    }

    /**
     * Empaqueta un String
     * 
     * @param v
     */
    public void putString(String v) {
	byte[] b = v.getBytes();
	putInt(b.length); // Para las cadenas, se guarda un //
			  // int con su longitud ... //
	try {
	    os.write(b); // ... y a continuacion los carac- //
			 // teres, como una secuencia de //
			 // bytes. //
	} catch (IOException ioe) {
	}
    }

    /**
     * Empaqueta una referencia a objeto.
     * 
     * @param or
     */
    public void putObj(ObjectRef or) {
	try { // Para una referencia a objeto ... //
	      // escribimos en primer lugar la IP
	      // del nodo en que
	      // se encuentra el objeto... //
	    putString(or.getHost());
	    // despues el numero de puerto donde//
	    // esta escuchando el ORB ... //
	    putInt(or.getPort());
	    // El identificador de//
	    // objeto con el que fue registrado //
	    // en ese ORB. //
	    putInt(or.getObid());
	    // Finalmente el id de la interfaz
	    putInt(or.getIid());
	} catch (Exception ioe) {
	}
    }

    /**
     * @param os
     *            the os to set
     */
    public void setOs(OutputStream os) {
	this.os = os;
    }

    /**
     * @return the os
     */
    public OutputStream getOs() {
	return os;
    }
}
